* raise minimum standards to c++17, Qt 5.12, MSVC 2017.
* avoid std::optional::value which didn't work until macOS 10.14.
* avoid std::optional::value which didn't work until macOS 10.14.
* update runner for codeql so we have Qt >= 5.12
* try harder to get codeql working with newer Qt.
* use c++17 fallthrough attribute.
* use c++17 'if constexpr' as suggested by resharper.
* catch mkicondoc up with c++17
analyze:
name: Analyze
runs-on: ubuntu-latest
- container: tsteven4/gpsbabel_build_environment
+ container: tsteven4/gpsbabel_build_environment_focal
strategy:
fail-fast: false
name: basic Build
runs-on: ubuntu-latest
container:
- image: gpsbabel-docker.jfrog.io/tsteven4/gpsbabel_build_environment
+ image: gpsbabel-docker.jfrog.io/tsteven4/gpsbabel_build_environment_focal
env:
LC_ALL: 'C.UTF-8'
VCVERSION: '14.16'
FLOW: 'nmake'
RELEASE: false
- - QT_VERSION: '5.12.10'
- ARCH: 'amd64'
- HOST_ARCH: 'x86'
- COMPILER: 'msvc2017_64'
- VCVERSION: '14.0'
- FLOW: 'nmake'
- RELEASE: false
- QT_VERSION: '5.12.10'
ARCH: 'x86'
HOST_ARCH: 'x86'
project(gpsbabel LANGUAGES C CXX)
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Find includes in corresponding build directories
# Find the Qt5Core library
find_package(Qt5 COMPONENTS Core REQUIRED)
-if(${Qt5Core_VERSION} VERSION_LESS 5.9)
+if(${Qt5Core_VERSION} VERSION_LESS 5.12)
message(FATAL_ERROR "Qt version ${Qt5Core_VERSION} found, but version 5.9 or newer is required.")
else()
message(STATUS "Using Qt5 version ${Qt5Core_VERSION}")
src/core/datetime.h
src/core/file.h
src/core/logging.h
- src/core/optional.h
src/core/textstream.h
src/core/usasciicodec.h
src/core/xmlstreamwriter.h
# Enforce minimum Qt version.
# versionAtLeast() was introduced in Qt 5.10, so we can't count on it being available.
-MIN_QT_VERSION = 5.9 # major[.minor[.patch]]
+MIN_QT_VERSION = 5.12 # major[.minor[.patch]]
MIN_QT_VERSION_COMPONENTS = $$split(MIN_QT_VERSION, .)
MIN_QT_VERSION_MAJOR = $$member(MIN_QT_VERSION_COMPONENTS, 0)
MIN_QT_VERSION_MINOR = $$member(MIN_QT_VERSION_COMPONENTS, 1)
CONFIG += console
CONFIG -= app_bundle
-CONFIG += c++14
+CONFIG += c++17
CONFIG += link_pkgconfig
TEMPLATE = app
src/core/datetime.h \
src/core/file.h \
src/core/logging.h \
- src/core/optional.h \
src/core/textstream.h \
src/core/usasciicodec.h \
src/core/xmlstreamwriter.h \
#include <cstdint> // for int32_t, uint32_t
#include <cstdio> // for NULL, fprintf, FILE, stdout
#include <ctime> // for time_t
+#include <optional> // for optional
#include <utility> // for move
#if HAVE_CONFIG_H
#include "gbfile.h" // doesn't really belong here, but is missing elsewhere.
#include "session.h" // for session_t
#include "src/core/datetime.h" // for DateTime
-#include "src/core/optional.h" // for optional
#define CSTR(qstr) ((qstr).toUtf8().constData())
*/
struct computed_trkdata {
double distance_meters{0.0};
- gpsbabel_optional::optional<double> max_alt; /* Meters */
- gpsbabel_optional::optional<double> min_alt; /* Meters */
- gpsbabel_optional::optional<double> max_spd; /* Meters/sec */
- gpsbabel_optional::optional<double> min_spd; /* Meters/sec */
- gpsbabel_optional::optional<double> avg_hrt; /* Avg Heartrate */
- gpsbabel_optional::optional<double> avg_cad; /* Avg Cadence */
+ std::optional<double> max_alt; /* Meters */
+ std::optional<double> min_alt; /* Meters */
+ std::optional<double> max_spd; /* Meters/sec */
+ std::optional<double> min_spd; /* Meters/sec */
+ std::optional<double> avg_hrt; /* Avg Heartrate */
+ std::optional<double> avg_cad; /* Avg Cadence */
gpsbabel::DateTime start; /* Min time */
gpsbabel::DateTime end; /* Max time */
- gpsbabel_optional::optional<int> min_hrt; /* Min Heartrate */
- gpsbabel_optional::optional<int> max_hrt; /* Max Heartrate */
- gpsbabel_optional::optional<int> max_cad; /* Max Cadence */
+ std::optional<int> min_hrt; /* Min Heartrate */
+ std::optional<int> max_hrt; /* Max Heartrate */
+ std::optional<int> max_cad; /* Max Cadence */
};
class route_head
#define ARG_NOMINMAX nullptr, nullptr
struct arglist_t {
- /* MSVC 2015 generates C2440, C2664 errors without some help. */
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
- arglist_t() = default;
- arglist_t(const char* astr, char** aval, const char* hstr, const char* dval,
- const uint32_t atyp, const char* minv, const char* maxv, char* avp) :
- argstring(astr),
- argval(aval),
- helpstring(hstr),
- defaultvalue(dval),
- argtype(atyp),
- minvalue(minv),
- maxvalue(maxv),
- argvalptr(avp) {}
-#endif
const char* argstring{nullptr};
char** argval{nullptr};
const char* helpstring{nullptr};
gpl_rd_init(const QString& fname)
{
gplfile_in = gbfopen_le(fname, "rb", MYNAME);
- if (sizeof(gpl_point_t) != 56) {
+ if constexpr (sizeof(gpl_point_t) != 56) {
fatal(MYNAME ": gpl_point is %zu instead of 56.\n",
sizeof(gpl_point_t));
}
switch (res) {
case Z_NEED_DICT:
res = Z_DATA_ERROR;
- /* fallthrough */
+ [[fallthrough]];
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
if (strcmp(cin, "1.0e25") == 0) {
break;
}
- /* fallthrough */
+ [[fallthrough]];
case WPT_cD_OFS + 1:
case WPT_cB_OFS + 6:
WAYPT_SET(wpt, temperature, atof(cin));
#define MYNAME "fit"
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr int GarminFitFormat::kTypeEnum;
-constexpr int GarminFitFormat::kTypeUint8;
-constexpr int GarminFitFormat::kTypeString;
-constexpr int GarminFitFormat::kTypeUint16;
-constexpr int GarminFitFormat::kTypeSint32;
-constexpr int GarminFitFormat::kTypeUint32;
-constexpr int GarminFitFormat::kCoursePointTypeLeft;
-constexpr int GarminFitFormat::kCoursePointTypeRight;
-#endif
-
/*******************************************************************************
* %%% global callbacks called by gpsbabel main process %%% *
*******************************************************************************/
/* Types */
struct fit_field_t {
- /* MSVC 2015 generates C2664 errors without some help. */
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
- fit_field_t() = default;
- fit_field_t(int i, int s, int t) : id(i), size(s), type(t) {}
-#endif
int id {};
int size{};
int type{};
};
struct tag_mapping {
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
- /* avoid MSVC 2015 C2664 errors. */
- tag_mapping() = default;
- tag_mapping(tag_type t, bool p) : type(t),passthrough(p) {}
-#endif
tag_type type{tt_unknown}; /* enum from above for this tag */
bool passthrough{true}; /* true if we don't generate this */
};
project(gpsbabelfe LANGUAGES CXX)
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Find includes in corresponding build directories
# Find the Qt5Core library
find_package(Qt5 COMPONENTS Core Gui Network Widgets Xml REQUIRED)
list(APPEND QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets Qt5::Xml)
-if(${Qt5Core_VERSION} VERSION_LESS 5.9)
+if(${Qt5Core_VERSION} VERSION_LESS 5.12)
message(FATAL_ERROR "Qt version ${Qt5Core_VERSION} found, but version 5.9 or newer is required.")
else()
message(STATUS "Using Qt5 version ${Qt5Core_VERSION}")
CONFIG(debug, debug|release) {
CONFIG += console
}
+CONFIG += c++17
ICON = images/appicon.icns
//------------------------------------------------------------------------
int main(int argc, char** argv)
{
-// MIN_QT_VERSION in configure.ac should correspond to the QT_VERSION_CHECK arguments in main.cc and gui/main.cc
-#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
+// MIN_QT_VERSION in GPSBabel.pro should correspond to the QT_VERSION_CHECK
+// arguments in main.cc and gui/main.cc and the version check in
+// CMakeLists.txt, gui/CMakeLists.txt.
+#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
#error this version of Qt is not supported.
#endif
#if FILTERS_ENABLED
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr double HeightFilter::geoid_grid_deg;
-constexpr double HeightFilter::geoid_scale;
-constexpr int HeightFilter::geoid_row;
-constexpr int HeightFilter::geoid_col;
-constexpr int8_t HeightFilter::geoid_delta[geoid_row][geoid_col];
-#endif
-
double HeightFilter::bilinear(double x1, double y1, double x2, double y2, double x, double y, double z11, double z12, double z21, double z22)
{
if (y1 == y2 && x1 == x2) {
#include <cstring> // for strcmp, strlen, strtok, strcat, strchr, strcpy, strncat
#include <ctime> // for gmtime, ctime
#include <iterator> // for reverse_iterator, operator==, prev, next
+#include <optional> // for optional
#include <QtCore/QByteArray> // for QByteArray
#include <QtCore/QList> // for QList<>::const_iterator
#include "cet_util.h" // for cet_convert_init
#include "gbfile.h" // for gbfprintf, gbfclose, gbfopen, gbfputs, gbfgetstr, gbfile
#include "src/core/datetime.h" // for DateTime
-#include "src/core/optional.h" // for optional
static gbfile* file_in, *file_out;
*/
static double interpolate_alt(const route_head* track, time_t time)
{
- static gpsbabel_optional::optional<WaypointList::const_iterator> prev_wpt;
- static gpsbabel_optional::optional<WaypointList::const_iterator> curr_wpt;
+ static std::optional<WaypointList::const_iterator> prev_wpt;
+ static std::optional<WaypointList::const_iterator> curr_wpt;
int time_diff;
// Start search at the beginning of the track
curr_wpt = track->waypoint_list.cbegin();
}
// Find the track points either side of the requested time
- while ((track->waypoint_list.cend() != curr_wpt.value()) &&
- ((*curr_wpt.value())->GetCreationTime().toTime_t() < time)) {
- prev_wpt = curr_wpt.value();
- curr_wpt = std::next(prev_wpt.value());
+ while ((track->waypoint_list.cend() != *curr_wpt) &&
+ ((**curr_wpt)->GetCreationTime().toTime_t() < time)) {
+ prev_wpt = *curr_wpt;
+ curr_wpt = std::next(*prev_wpt);
}
- if (track->waypoint_list.cend() == curr_wpt.value()) {
+ if (track->waypoint_list.cend() == *curr_wpt) {
// Requested time later than all track points, we can't interpolate
return unknown_alt;
}
- if (track->waypoint_list.cbegin() == curr_wpt.value()) {
- if ((*curr_wpt.value())->GetCreationTime().toTime_t() == time) {
+ if (track->waypoint_list.cbegin() == *curr_wpt) {
+ if ((**curr_wpt)->GetCreationTime().toTime_t() == time) {
// First point's creation time is an exact match so use it's altitude
- return (*curr_wpt.value())->altitude;
+ return (**curr_wpt)->altitude;
} else {
// Requested time is prior to any track points, we can't interpolate
return unknown_alt;
}
}
// Interpolate
- if (0 == (time_diff = (*curr_wpt.value())->GetCreationTime().toTime_t() - (*prev_wpt.value())->GetCreationTime().toTime_t())) {
+ if (0 == (time_diff = (**curr_wpt)->GetCreationTime().toTime_t() - (**prev_wpt)->GetCreationTime().toTime_t())) {
// Avoid divide by zero
- return (*curr_wpt.value())->altitude;
+ return (**curr_wpt)->altitude;
}
- double alt_diff = (*curr_wpt.value())->altitude - (*prev_wpt.value())->altitude;
- return (*prev_wpt.value())->altitude + (alt_diff / time_diff) * (time - (*prev_wpt.value())->GetCreationTime().toTime_t());
+ double alt_diff = (**curr_wpt)->altitude - (**prev_wpt)->altitude;
+ return (**prev_wpt)->altitude + (alt_diff / time_diff) * (time - (**prev_wpt)->GetCreationTime().toTime_t());
}
/*
// Sanity check
static void igo8_check_type_sizes()
{
- if (sizeof(igo8_point) != 12) {
+ if constexpr (sizeof(igo8_point) != 12) {
fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n",
(long) sizeof(igo8_point));
}
- if (sizeof(igo8_information_block) != 12) {
+ if constexpr (sizeof(igo8_information_block) != 12) {
fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n",
(long) sizeof(igo8_information_block));
}
- if (sizeof(igo8_id_block) != 20) {
+ if constexpr (sizeof(igo8_id_block) != 20) {
fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n",
(long) sizeof(igo8_id_block));
}
#include <climits> // for INT_MAX
#include <cmath> // for abs, ceil, isfinite, round
#include <cstdlib> // for abs, atoi, strtod
+#include <optional> // for optional
#include <QtCore/QString> // for QString
#include <QtCore/QtGlobal> // for qAsConst, QAddConst<>::Type
#include "grtcirc.h" // for linepart, RAD, gcdist, radtomiles
#include "src/core/datetime.h" // for DateTime
#include "src/core/logging.h" // for Fatal
-#include "src/core/optional.h" // for optional
#if FILTERS_ENABLED
if (first) {
first = false;
} else {
- gpsbabel_optional::optional<qint64> timespan;
+ std::optional<qint64> timespan;
if (wpt->creation_time.isValid() && time1.isValid()) {
timespan = wpt->creation_time.toMSecsSinceEpoch() -
time1.toMSecsSinceEpoch();
}
- gpsbabel_optional::optional<double> altspan;
+ std::optional<double> altspan;
if (altitude1 != unknown_alt && wpt->altitude != unknown_alt) {
altspan = wpt->altitude - altitude1;
}
fatal(FatalMsg() << MYNAME ": points must have valid times to interpolate by time!");
}
// interpolate even if time is running backwards.
- npts = std::abs(timespan.value()) / max_time_step;
+ npts = std::abs(*timespan) / max_time_step;
} else if (opt_dist != nullptr) {
double distspan = radtomiles(gcdist(RAD(lat1),
RAD(lon1),
wpt_new->description = QString();
if (timespan.has_value()) {
wpt_new->SetCreationTime(0, time1.toMSecsSinceEpoch() +
- round(frac * timespan.value()));
+ round(frac * *timespan));
} else {
wpt_new->creation_time = gpsbabel::DateTime();
}
&wpt_new->latitude,
&wpt_new->longitude);
if (altspan.has_value()) {
- wpt_new->altitude = altitude1 + (frac * altspan.value());
+ wpt_new->altitude = altitude1 + (frac * *altspan);
} else {
wpt_new->altitude = unknown_alt;
}
#ifndef INTERPOLATE_H_INCLUDED_
#define INTERPOLATE_H_INCLUDED_
+#include <optional> // for optional
+
#include <QtCore/QVector> // for QVector
#include <QtCore/QtGlobal> // for qint64
#include "defs.h" // for ARG_NOMINMAX, arglist_t, ARGTYPE_BEGIN_EXCL, ARG...
#include "filter.h" // for Filter
-#include "src/core/optional.h" // for optional
#if FILTERS_ENABLED
#include <cstdio> // for sscanf, printf
#include <cstdlib> // for atoi, atol, atof
#include <cstring> // for strcmp
+#include <optional> // for optional
#include <tuple> // for tuple, make_tuple, tie
#include <QtCore/QByteArray> // for QByteArray
#include "src/core/datetime.h" // for DateTime
#include "src/core/file.h" // for File
#include "src/core/logging.h" // for Warning, Fatal
-#include "src/core/optional.h" // for optional
#include "src/core/xmlstreamwriter.h" // for XmlStreamWriter
#include "src/core/xmltag.h" // for xml_findfirst, xml_tag, fs_xml, xml_attribute, xml_findnext
#include "units.h" // for fmt_setunits, fmt_speed, fmt_altitude, fmt_distance, units_aviation, units_metric, units_nautical, units_statute
#define MYNAME "Lowrance USR"
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr int LowranceusrFormat::DEF_ICON;
-constexpr int LowranceusrFormat::X_1_ICON;
-constexpr const char* LowranceusrFormat::DISABLED_CACHE_TXT;
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
-constexpr LowranceusrFormat::lowranceusr_icon_mapping_t LowranceusrFormat::lowranceusr_icon_value_table[];
-#else
-constexpr LowranceusrFormat::lowranceusr_icon_mapping_t LowranceusrFormat::lowranceusr_icon_value_table[134];
-#endif
-constexpr int LowranceusrFormat::DEF_USR4_ICON;
-constexpr int LowranceusrFormat::DEF_USR4_COLOR;
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
-constexpr LowranceusrFormat::lowranceusr4_icon_mapping_t LowranceusrFormat::lowranceusr4_icon_value_table[];
-#else
-constexpr LowranceusrFormat::lowranceusr4_icon_mapping_t LowranceusrFormat::lowranceusr4_icon_value_table[22];
-#endif
-constexpr int LowranceusrFormat::MAXUSRSTRINGSIZE;
-constexpr double LowranceusrFormat::SEMIMINOR;
-constexpr double LowranceusrFormat::DEGREESTORADIANS;
-constexpr int LowranceusrFormat::MAX_TRAIL_POINTS;
-constexpr double LowranceusrFormat::UNKNOWN_USR_ALTITUDE;
-constexpr time_t LowranceusrFormat::base_time_secs;
-#endif
-
/* below couple of functions mostly borrowed from raymarine.c */
/* make waypoint shortnames unique */
static constexpr int X_1_ICON = 10003;
static constexpr const char* DISABLED_CACHE_TXT = "Disabled Cache";
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
static constexpr lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = {
-#else
- static constexpr lowranceusr_icon_mapping_t lowranceusr_icon_value_table[134] = {
-#endif
/* Taken from iFinder 1.8 */
static constexpr int DEF_USR4_ICON = 2;
static constexpr int DEF_USR4_COLOR = 0;
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
static constexpr lowranceusr4_icon_mapping_t lowranceusr4_icon_value_table[] = {
-#else
- static constexpr lowranceusr4_icon_mapping_t lowranceusr4_icon_value_table[22] = {
-#endif
/* USR GPX Symbol COLOR1 COLOR2 COLOR3 COLOR4 COLOR5 COLOR6 COLOR7 HOOK2 Displays */
int rc = 0;
const char* prog_name = argv[0]; /* may not match QCoreApplication::arguments().at(0)! */
-// MIN_QT_VERSION in configure.ac should correspond to the QT_VERSION_CHECK arguments in main.cc and gui/main.cc
-#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
+// MIN_QT_VERSION in GPSBabel.pro should correspond to the QT_VERSION_CHECK
+// arguments in main.cc and gui/main.cc and the version check in
+// CMakeLists.txt, gui/CMakeLists.txt.
+#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
#error This version of Qt is not supported.
#endif
+#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
+#error MSVC 2015 and earlier are not supported. Please use MSVC 2017 or MSVC 2019.
+#endif
+
#ifdef DEBUG_LOCALE
printf("Initial locale: %s\n",setlocale(LC_ALL, NULL));
#endif
CONFIG += console
CONFIG -= app_bundle
-CONFIG += c++14
+CONFIG += c++17
TEMPLATE = app
#include <cstddef> // for nullptr_t
#include <algorithm> // for sort
#include <iterator>
+#include <optional> // for optional, operator>, operator<
#include <QtCore/QDateTime> // for QDateTime
#include <QtCore/QList> // for QList<>::iterator
#include "grtcirc.h" // for RAD, gcdist, heading_true_degrees, radtometers
#include "session.h" // for curr_session, session_t (ptr only)
#include "src/core/datetime.h" // for DateTime
-#include "src/core/optional.h" // for optional, operator>, operator<
RouteList* global_route_list;
case 0xc: /* POI item (same structure as full) */
poi = 1;
- /* fallthrough */
+ [[fallthrough]];
case 0x2: /* Multi HZ item */
if (len < MULTI_HZ_ITEM_LEN) {
case 0x6: /* POI item (same structure as full) */
poi = 1;
- /* fallthrough */
+ [[fallthrough]];
case 0x4: /* full item */
if (len < FULL_ITEM_LEN) {
--- /dev/null
+/*
+ Copyright (C) 2018 Robert Lipe, robertlipe@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+// someday, when we require c++17,
+// the intent is that this can all go away by
+// changing:
+// 1. 'gpsbabel_optional::optional' to 'std::optional',
+// 2. 'include "optional.h"' becomes 'include <optional>'.
+
+#ifndef GPSBABEL_OPTIONAL_H_INCLUDED_
+#define GPSBABEL_OPTIONAL_H_INCLUDED_
+
+#if __cplusplus >= 201703L
+#warning "using std::optional"
+#include <optional>
+#define gpsbabel_optional std
+#else
+#include <cassert>
+namespace gpsbabel_optional
+{
+template<typename T>
+class optional
+{
+private:
+ bool null{true};
+ T v{};
+
+public:
+ constexpr optional() noexcept = default;
+ explicit optional(T n) : null{false}, v{n} {}
+
+ // There is a known mismatch with std::optional.
+ // o = {}; should act like reset() so o.has_value() returns false.
+ // instead o.has_value() returns true and o.value() returns 0.
+ optional& operator=(const T& rhs)
+ {
+ null = false;
+ v = rhs;
+ return *this;
+ }
+
+ // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
+ // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
+ // intentionally does not check to see if a value is contained, use value() for that.
+ const T& operator*() const&
+ {
+ return v;
+ }
+
+ // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
+ // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
+ // intentionally does not check to see if a value is contained, use value() for that.
+ T& operator*()&
+ {
+ return v;
+ }
+
+ constexpr explicit operator bool() const noexcept
+ {
+ return !null;
+ }
+
+ constexpr bool has_value() const noexcept
+ {
+ return !null;
+ }
+
+ // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
+ // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
+ // if constexpr cannot use assert.
+ T& value() &
+ {
+ assert(!null);
+ return v;
+ }
+
+ // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
+ // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
+ // if constexpr cannot use assert.
+ const T& value() const&
+ {
+ assert(!null);
+ return v;
+ }
+
+ void reset() noexcept
+ {
+ null = true;
+ }
+};
+
+template< class T, class U >
+constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (bool(lhs) != bool(rhs)) {
+ return false;
+ }
+ if (bool(lhs) == false) {
+ return true;
+ }
+ return *lhs == *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (bool(lhs) != bool(rhs)) {
+ return true;
+ }
+ if (bool(lhs) == false) {
+ return false;
+ }
+ return *lhs != *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (!rhs) {
+ return false;
+ }
+ if (!lhs) {
+ return true;
+ }
+ return *lhs < *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (!lhs) {
+ return false;
+ }
+ if (!rhs) {
+ return true;
+ }
+ return *lhs > *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (!lhs) {
+ return true;
+ }
+ if (!rhs) {
+ return false;
+ }
+ return *lhs <= *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs)
+{
+ if (!rhs) {
+ return true;
+ }
+ if (!lhs) {
+ return false;
+ }
+ return *lhs >= *rhs;
+}
+
+
+template< class T, class U >
+constexpr bool operator==(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? (*opt == value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator==(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? (value == *opt) : false;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? (*opt != value) : true;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? (value != *opt) : true;
+}
+
+template< class T, class U >
+constexpr bool operator<(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? (*opt < value) : true;
+}
+
+template< class T, class U >
+constexpr bool operator<(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? (value < *opt) : false;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? *opt <= value : true;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? value <= *opt : false;
+}
+
+template< class T, class U >
+constexpr bool operator>(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? (*opt > value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator>(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? (value > *opt) : true;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const optional<T>& opt, const U& value)
+{
+ return bool(opt) ? (*opt >= value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const T& value, const optional<U>& opt)
+{
+ return bool(opt) ? (value >= *opt) : true;
+}
+
+} // namespace
+#endif
+
+#endif // GPSBABEL_OPTIONAL_H_INCLUDED_
+++ /dev/null
-/*
- Copyright (C) 2018 Robert Lipe, robertlipe@gpsbabel.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- */
-
-// someday, when we require c++17,
-// the intent is that this can all go away by
-// changing:
-// 1. 'gpsbabel_optional::optional' to 'std::optional',
-// 2. 'include "optional.h"' becomes 'include <optional>'.
-
-#ifndef GPSBABEL_OPTIONAL_H_INCLUDED_
-#define GPSBABEL_OPTIONAL_H_INCLUDED_
-
-#if __cplusplus >= 201703L
-#warning "using std::optional"
-#include <optional>
-#define gpsbabel_optional std
-#else
-#include <cassert>
-namespace gpsbabel_optional
-{
-template<typename T>
-class optional
-{
-private:
- bool null{true};
- T v{};
-
-public:
- constexpr optional() noexcept = default;
- explicit optional(T n) : null{false}, v{n} {}
-
- // There is a known mismatch with std::optional.
- // o = {}; should act like reset() so o.has_value() returns false.
- // instead o.has_value() returns true and o.value() returns 0.
- optional& operator=(const T& rhs)
- {
- null = false;
- v = rhs;
- return *this;
- }
-
- // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
- // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
- // intentionally does not check to see if a value is contained, use value() for that.
- const T& operator*() const&
- {
- return v;
- }
-
- // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
- // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
- // intentionally does not check to see if a value is contained, use value() for that.
- T& operator*()&
- {
- return v;
- }
-
- constexpr explicit operator bool() const noexcept
- {
- return !null;
- }
-
- constexpr bool has_value() const noexcept
- {
- return !null;
- }
-
- // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
- // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
- // if constexpr cannot use assert.
- T& value() &
- {
- assert(!null);
- return v;
- }
-
- // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
- // but MSVC2015 with the c++14 standard can't handle it. MSVC2017 is ok.
- // if constexpr cannot use assert.
- const T& value() const&
- {
- assert(!null);
- return v;
- }
-
- void reset() noexcept
- {
- null = true;
- }
-};
-
-template< class T, class U >
-constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (bool(lhs) != bool(rhs)) {
- return false;
- }
- if (bool(lhs) == false) {
- return true;
- }
- return *lhs == *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (bool(lhs) != bool(rhs)) {
- return true;
- }
- if (bool(lhs) == false) {
- return false;
- }
- return *lhs != *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (!rhs) {
- return false;
- }
- if (!lhs) {
- return true;
- }
- return *lhs < *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (!lhs) {
- return false;
- }
- if (!rhs) {
- return true;
- }
- return *lhs > *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (!lhs) {
- return true;
- }
- if (!rhs) {
- return false;
- }
- return *lhs <= *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs)
-{
- if (!rhs) {
- return true;
- }
- if (!lhs) {
- return false;
- }
- return *lhs >= *rhs;
-}
-
-
-template< class T, class U >
-constexpr bool operator==(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? (*opt == value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator==(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? (value == *opt) : false;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? (*opt != value) : true;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? (value != *opt) : true;
-}
-
-template< class T, class U >
-constexpr bool operator<(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? (*opt < value) : true;
-}
-
-template< class T, class U >
-constexpr bool operator<(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? (value < *opt) : false;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? *opt <= value : true;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? value <= *opt : false;
-}
-
-template< class T, class U >
-constexpr bool operator>(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? (*opt > value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator>(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? (value > *opt) : true;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const optional<T>& opt, const U& value)
-{
- return bool(opt) ? (*opt >= value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const T& value, const optional<U>& opt)
-{
- return bool(opt) ? (value >= *opt) : true;
-}
-
-} // namespace
-#endif
-
-#endif // GPSBABEL_OPTIONAL_H_INCLUDED_
return 0; /* incomplete escape sequence */
}
/* pass-through next character */
- /* fallthrough */
+ [[fallthrough]];
default:
if (*m != *s) {
char* cdest = (char*) dest;
const char* csrc = (const char*) src;
- if (i_am_little_endian) {
+ if constexpr (i_am_little_endian) {
memcpy(dest, src, 8);
} else {
int i;
#include <cstdlib> // for atof, atoi, strtod
#include <cstring> // for strlen, strncmp, strcmp, memset
#include <ctime> // for gmtime, localtime, time_t, mktime, strftime
+#include <optional> // for optional
#include <QtCore/QByteArray> // for QByteArray
#include <QtCore/QChar> // for QChar
#include "session.h" // for session_t
#include "src/core/datetime.h" // for DateTime
#include "src/core/logging.h" // for FatalMsg
-#include "src/core/optional.h" // for optional
#include "src/core/textstream.h" // for TextStream
#include "strptime.h" // for strptime
#include "xcsv.h"
// If XT_LAT_DIR(XT_LON_DIR) was an input field, and the latitude(longitude) is positive,
// assume the latitude(longitude) was the absolute value and take the sign from XT_LAT_DIR(XT_LON_DIR).
- if (parse_data.lat_dir_positive.has_value() && !parse_data.lat_dir_positive.value() && (wpt_tmp->latitude > 0.0)) {
+ if (parse_data.lat_dir_positive.has_value() && !(*parse_data.lat_dir_positive) && (wpt_tmp->latitude > 0.0)) {
wpt_tmp->latitude = -wpt_tmp->latitude;
}
- if (parse_data.lon_dir_positive.has_value() && !parse_data.lon_dir_positive.value() && (wpt_tmp->longitude > 0.0)) {
+ if (parse_data.lon_dir_positive.has_value() && !(*parse_data.lon_dir_positive) && (wpt_tmp->longitude > 0.0)) {
wpt_tmp->longitude = -wpt_tmp->longitude;
}
#define XCSV_H_INCLUDED_
#include <ctime>
+#include <optional> // for optional
#include <utility> // for move
#include <QtCore/QByteArray> // for QByteArray
#include "format.h"
#include "garmin_fs.h"
#include "src/core/datetime.h" // for DateTime
-#include "src/core/optional.h" // for optional
#include "src/core/textstream.h" // for TextStream
#if CSVFMTS_ENABLED
gpsdata_type datatype{unknown_gpsdata};
/* SHORTLEN from style file */
- gpsbabel_optional::optional<int> shortlen;
+ std::optional<int> shortlen;
/* SHORTWHITE from style file */
- gpsbabel_optional::optional<int> whitespace_ok;
+ std::optional<int> whitespace_ok;
private:
/* Types */
double utm_zone{0};
char utm_zonec{'N'};
UrlLink* link_{nullptr};
- gpsbabel_optional::optional<bool> lat_dir_positive;
- gpsbabel_optional::optional<bool> lon_dir_positive;
+ std::optional<bool> lat_dir_positive;
+ std::optional<bool> lon_dir_positive;
};
/* Constants */